
// ===============================================================================================================
// -*- C++ -*-
//
// CommLib.hpp - Commom code and definitions used everywhere.
//
// Copyright (c) 2011 Guilherme R. Lampert
// guilherme.ronaldo.lampert@gmail.com
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

#ifndef __COMMLIB_HPP__
#define __COMMLIB_HPP__

#if defined (_MSC_VER)
/* Disable the CRT lib deprecation warning */
#pragma warning (disable: 4996)
/* Unreferenced local function (GLUT warning) */
#pragma warning (disable: 4505)
#endif // _MSC_VER

// C++ std includes
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <io.h>

namespace CommLib {

// =========================================================
// Templates / Inline Routines
// =========================================================

// Swap without checking.
template<typename T> static inline void SwapFast(T & lhs, T & rhs)
{
	T tmp = lhs;
	lhs = rhs;
	rhs = tmp;
}

// Packs 3 color bytes inside an integer. The last channel is set to 255.
static inline unsigned long PackRGB(unsigned char r, unsigned char g, unsigned char b)
{
	return (static_cast<unsigned long>(((0xff << 24) | (((b) & 0xff) << 16) | (((g) & 0xff) << 8) | ((r) & 0xff))));
}

// Packs 4 color bytes inside an integer.
static inline unsigned long PackRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
	return (static_cast<unsigned long>((((a) & 0xff) << 24) | (((b) & 0xff) << 16) | (((g) & 0xff) << 8) | ((r) & 0xff)));
}

// =========================================================
// Misc Functions
// =========================================================

// Return the number of frames per second. Must be called inside the rendering loop, every frame.
int CalcFPS(void);

// Returns the elapsed milliseconds since the last call to the function.
float GetElapsedMilliseconds(void);

// Returns the elapsed seconds since the last call to the function.
float GetElapsedSeconds(void);

// Directory Searching:
#define FILE_ARCH    0x01 // Archive file
#define FILE_HIDDEN  0x02 // Hidden file
#define FILE_RDONLY  0x04 // Read only file
#define FILE_SUBDIR  0x08 // Subdirectory
#define FILE_SYSTEM  0x10 // System file

// Returns the path up to, but not including the last '/'
void FileGetPath(const char * in, char * out);

// Compare file attributes.
bool FileCompareAttributes(unsigned int found, unsigned int mustHave, unsigned int cantHave);

// Find the first file in an open directory.
char * FileFindFirst(const char * path, unsigned int mustHave, unsigned int cantHave);

// Find the next file in an open directory.
char * FileFindNext(unsigned int mustHave, unsigned int cantHave);

// Close the file search.
void FileFindClose(void);

// =========================================================
// Debugging
// =========================================================

// Verbosity levels
#define VL_PRINT_ALL      2
#define VL_PRINT_ERR      0
#define VL_PRINT_WARN_ERR 1
#define VL_PRINT_NONE    -1

// Global verbosity level
extern int verbosityLevel;

// Message status for DbgPrintf()
#define PRINT_MSG   2
#define PRINT_WARN  1
#define PRINT_ERROR 0

// Print message to default outputs based on global verbosity level. Breaks line by default
void DbgPrintf(int verbosity, const char * format, ...);

}; // namespace CommLib {}

#endif // __COMMLIB_HPP__